package org.ainlolcat.ainscience.UI;

import org.ainlolcat.ainscience.Controller;
import org.ainlolcat.ainscience.column.Column;
import org.ainlolcat.ainscience.column.threshold.Threshold;
import org.ainlolcat.ainscience.entity.Entity;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.regex.Pattern;

/**
 * @author ainlolcat
 *         Date: 5/2/13
 */
public class ExcelStatisticsExporter {
    private static Logger log = Logger.getLogger(ExcelStatisticsExporter.class);
    static Pattern digit = Pattern.compile("\\d+(.\\d+)?");
    String mode = "o";

    public String getMode() {
        return mode;
    }

    public void setMode(String mode) {
        this.mode = mode;
    }

    public void export(Entity entity,  String filename){
        Workbook workbook = null;
        Sheet firstSheet = null;
        if (mode.equals("a") && new File(filename).exists()){
            try {
                workbook = WorkbookFactory.create(new File(filename));
            } catch (Exception e) {
                log.error(e);
                workbook = new HSSFWorkbook();
            }
            firstSheet = workbook.getSheet("Statistics");
        } else {
            workbook = new HSSFWorkbook();
            firstSheet = workbook.createSheet("Statistics");
        }

        CellStyle warningStyle = workbook.createCellStyle();
        warningStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
        warningStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
        CellStyle criticalStyle = workbook.createCellStyle();
        criticalStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
        criticalStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);

        int rows = firstSheet.getPhysicalNumberOfRows();

        if (rows == 0){
            Row nameRow = firstSheet.createRow(0);
            for (int i = 0; i < entity.getColumnCount(); i++){
                nameRow.createCell(i).setCellValue(entity.getColumnByOrder(i).getName());
            }
            firstSheet.createFreezePane( 0, 1, 0, 1 );
            rows++;
        }
        Row entityId = firstSheet.createRow(rows);
        firstSheet.addMergedRegion(new CellRangeAddress(
                rows, //first row (0-based)
                rows, //last row  (0-based)
                0, //first column (0-based)
                entity.getColumnCount() - 1  //last column  (0-based)
        ));
        entityId.createCell(0).setCellValue(Controller.getInstance().getProject().getHomeDir());
        rows++;
        for (int i = 0; i < entity.getRowCount(); i++){
            Row valuesRow = firstSheet.createRow(rows);
            for (int j=0;j<entity.getColumnCount();j++){
                Cell cell = valuesRow.createCell(j);
                cell.setCellValue(String.valueOf(entity.getColumnByOrder(j).getValue(i)));
                Column c = entity.getColumnByOrder(j);
                boolean critical = false;
                boolean warning = false;
                boolean filtered = false;
                boolean wholeRow = false;
                if (c.getThresholds() != null)
                    for (Threshold t: c.getThresholds()){
                        if (t.isExceed(entity, j,i)){
                            if (t.isFilter())
                                filtered = true;
                            wholeRow = wholeRow || !t.isLocalFilter();
                            if (t.getType() == Threshold.WARRNING)
                                warning = true;
                            else
                                critical = true;
                        }
                    }
                if (filtered){
                    if (wholeRow){
                        firstSheet.removeRow(valuesRow);
                        rows--;
                        break;
                    } else {
                        valuesRow.removeCell(cell);
                    }
                }  else {
                    if (warning)
                        cell.setCellStyle(warningStyle);
                    if (critical)
                        cell.setCellStyle(criticalStyle);
                }
            }
            rows++;
        }

        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(new File(filename));
            workbook.write(fos);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.flush();
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
